home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * obj -
- * Some utilities for reading a writing geometric objects.
- *
- * Paul Haeberli - 1985
- */
- #include "obj.h"
-
- static tokentofile();
- static tofile();
-
- static int dowriteattrs;
- static int dowritebinary;
-
- #define ATTR_TOKEN 0
- #define POINT_TOKEN 0
- #define LINE_TOKEN 1
- #define LOOP_TOKEN 2
- #define POLY_TOKEN 3
-
- /*
- * fast point alloc and free
- *
- */
- #define NINCHUNK 100
-
- static point *fpnts;
-
- static point *pntmalloc()
- {
- point *p;
- int i;
-
- if(!fpnts) {
- p = (point *)mymalloc(NINCHUNK*sizeof(point));
- for(i=0; i<NINCHUNK; i++)
- freepnt(p++);
- }
- p = fpnts;
- fpnts = fpnts->next;
- return p;
- }
-
- freepnt(pnt)
- point *pnt;
- {
- if( pnt ) {
- pnt->next = fpnts;
- fpnts = pnt;
- }
- }
-
- writeattrs(f)
- int f;
- {
- dowriteattrs = f;
- }
-
- writebinary(f)
- int f;
- {
- dowritebinary = f;
- }
-
- writeobj(outf,obj)
- FILE *outf;
- object *obj;
- {
- if(dowritebinary) {
- putstr(outf,"binarygeom");
- putnewline(outf);
- while(obj) {
- if(dowriteattrs && obj->attr)
- putattr(outf,obj->attr);
- if(obj->type == OBJ_POINTS) {
- tokentofile(outf,POINT_TOKEN);
- putpoints(outf,obj->points);
- } else if(obj->type == OBJ_LINE) {
- tokentofile(outf,LINE_TOKEN);
- putpoints(outf,obj->points);
- } else if(obj->type == OBJ_LOOP) {
- tokentofile(outf,LOOP_TOKEN);
- putpoints(outf,obj->points);
- } else if(obj->type == OBJ_POLYGON) {
- tokentofile(outf,POLY_TOKEN);
- putpoints(outf,obj->points);
- } else
- printf("writeobj: blat\n");
- obj = obj->next;
- }
- } else {
- while(obj) {
- if(dowriteattrs && obj->attr)
- putattr(outf,obj->attr);
- if(obj->type == OBJ_POINTS) {
- putstr(outf,"beginpoints");
- putnewline(outf);
- putpoints(outf,obj->points);
- putstr(outf,"endpoints");
- putnewline(outf);
- } else if(obj->type == OBJ_LINE) {
- putstr(outf,"beginline");
- putnewline(outf);
- putpoints(outf,obj->points);
- putstr(outf,"endline");
- putnewline(outf);
- } else if(obj->type == OBJ_LOOP) {
- putstr(outf,"beginloop");
- putnewline(outf);
- putpoints(outf,obj->points);
- putstr(outf,"endloop");
- putnewline(outf);
- } else if(obj->type == OBJ_POLYGON) {
- putstr(outf,"beginpoly");
- putnewline(outf);
- putpoints(outf,obj->points);
- putstr(outf,"endpoly");
- putnewline(outf);
- } else
- printf("writeobj: blat\n");
- obj = obj->next;
- }
- }
- }
-
- putpoints(outf,pnt)
- FILE *outf;
- point *pnt;
- {
- if(dowritebinary) {
- while(pnt) {
- if(dowriteattrs && pnt->attr)
- putattr(outf,pnt->attr);
- tokentofile(outf,ATTR_TOKEN);
- tofile(outf,&pnt->x,3*sizeof(float));
- pnt = pnt->next;
- }
- } else {
- while(pnt) {
- if(dowriteattrs && pnt->attr)
- putattr(outf,pnt->attr);
- putstr(outf,"\tpnt");
- putfloat(outf,pnt->x);
- putfloat(outf,pnt->y);
- putfloat(outf,pnt->z);
- putnewline(outf);
- pnt = pnt->next;
- }
- }
- }
-
- static tofile(outf,data,len)
- FILE *outf;
- char *data;
- int len;
- {
- fwrite(data,1,len,outf);
- }
-
- static tokentofile(outf,token)
- FILE *outf;
- int token;
- {
- fwrite(&token,1,sizeof(int),outf);
- }
-
- putattr(outf,attr)
- FILE *outf;
- attribs *attr;
- {
- if(dowritebinary) {
- tokentofile(outf,ATTR_TOKEN);
- tofile(outf,attr,6*sizeof(float));
- } else {
- putstr(outf,"\tattr");
- putfloat(outf,attr->r);
- putfloat(outf,attr->g);
- putfloat(outf,attr->b);
- putfloat(outf,attr->nx);
- putfloat(outf,attr->ny);
- putfloat(outf,attr->nz);
- putnewline(outf);
- }
- }
-
- moveobj(obj,dx,dy,dz)
- object *obj;
- float dx, dy, dz;
- {
- point *pnt;
-
- while(obj) {
- pnt = obj->points;
- while(pnt) {
- pnt->x += dx;
- pnt->y += dy;
- pnt->z += dz;
- pnt = pnt->next;
- }
- obj = obj->next;
- }
- }
-
- object *newobj()
- {
- object *obj;
-
- obj = (object *)mymalloc(sizeof(object));
- obj->next = NULL;
- obj->type = OBJ_LINE;
- obj->attr = NULL;
- obj->points = NULL;
- return obj;
- }
-
- attribs *newattr()
- {
- attribs *attr;
- attr = (attribs *)mymalloc(sizeof(attribs));
- attr->r = 0.0;
- attr->g = 0.0;
- attr->b = 0.0;
- attr->nx = 0.0;
- attr->ny = 0.0;
- attr->nz = 0.0;
- }
-
- freeattr(attr)
- attribs *attr;
- {
- free(attr);
- }
-
- attribs *cloneattr(attr)
- attribs *attr;
- {
- attribs *cattr;
-
- cattr = (attribs *)mymalloc(sizeof(attribs));
- *cattr = *attr;
- return cattr;
- }
-
- point *newpnt(x,y,z)
- float x, y, z;
- {
- point *pnt;
-
- pnt = pntmalloc();
- pnt->next = NULL;
- pnt->type = PNT_SQUARE;
- pnt->attr = NULL;
- pnt->x = x;
- pnt->y = y;
- pnt->z = z;
- return pnt;
- }
-
- point *clonepnt(pnt)
- point *pnt;
- {
- point *cpnt;
-
- cpnt = pntmalloc();
- cpnt->next = NULL;
- cpnt->type = pnt->type;
- if(pnt->attr)
- cpnt->attr = cloneattr(pnt->attr);
- else
- cpnt->attr = NULL;
- cpnt->x = pnt->x;
- cpnt->y = pnt->y;
- cpnt->z = pnt->z;
- return cpnt;
- }
-
- addpoint(obj,pnt)
- object *obj;
- point *pnt;
- {
- point *cpnt;
-
- pnt->next = NULL;
- if(obj->points) {
- cpnt = obj->points;
- while(cpnt->next)
- cpnt = cpnt->next;
- cpnt->next = pnt;
- } else
- obj->points = pnt;
- }
-
- addobject(obj,nobj)
- object *obj, *nobj;
- {
- object *cobj;
-
- if(obj->next) {
- cobj = obj->next;
- while(cobj->next)
- cobj = cobj->next;
- cobj->next = nobj;
- } else
- obj->next = nobj;
- }
-
- freepnts(pnt)
- point *pnt;
- {
- point *npnt;
-
- while(pnt) {
- npnt = pnt->next;
- if(pnt->attr)
- freeattr(pnt->attr);
- freepnt(pnt);
- pnt = npnt;
- }
- }
-
- freeobj(obj)
- object *obj;
- {
- object *nobj;
-
- while(obj) {
- nobj = obj->next;
- freepnts(obj->points);
- if(obj->attr)
- free(obj->attr);
- free(obj);
- obj = nobj;
- }
- }
-
- object *objfromfile(name)
- char *name;
- {
- object *obj;
- FILE *inf;
-
- inf = fopen(name,"r");
- if(!inf) {
- fprintf(stderr,"objfromfile: can't open file %s\n",name);
- return 0;
- }
- obj = getobj(inf);
- fclose(inf);
- return obj;
- }
-
- objtofile(name,obj)
- char *name;
- object *obj;
- {
- FILE *of;
-
- of = fopen(name,"w");
- if(!of) {
- fprintf(stderr,"objtofile: can't open file %s\n",name);
- return 0;
- }
- writeobj(of,obj);
- fclose(of);
- }
-
- object *getobj(inf)
- FILE *inf;
- {
- float x, y, z;
- object *objlist;
- object *curobj;
- point *npnt;
- attribs *attr;
- char buf[512];
-
- attr = 0;
- objlist = NULL;
- while(getstr(inf,buf)) {
- if(*buf == 0) {
- ;
- } else if(strcmp(buf,"beginpoly") == 0) {
- getnewline(inf);
- curobj = newobj();
- curobj->type = OBJ_POLYGON;
- curobj->next = objlist;
- curobj->attr = attr;
- objlist = curobj;
- while(getstr(inf,buf)) {
- if(strcmp(buf,"pnt") == 0) {
- x = getfloat(inf);
- y = getfloat(inf);
- z = getfloat(inf);
- getnewline(inf);
- npnt = newpnt(x,y,z);
- npnt->attr = attr;
- addpoint(curobj,npnt);
- } else if(strcmp(buf,"endpoly") == 0) {
- getnewline(inf);
- break;
- } else if(strcmp(buf,"attr") == 0) {
- attr = newattr();
- attr->r = getfloat(inf);
- attr->g = getfloat(inf);
- attr->b = getfloat(inf);
- attr->nx = getfloat(inf);
- attr->ny = getfloat(inf);
- attr->nz = getfloat(inf);
- getnewline(inf);
- } else
- printf("getobj: bblat\n");
- }
- } else if(strcmp(buf,"beginline") == 0) {
- getnewline(inf);
- curobj = newobj();
- curobj->type = OBJ_LINE;
- curobj->next = objlist;
- objlist = curobj;
- while(getstr(inf,buf)) {
- if(strcmp(buf,"pnt") == 0) {
- x = getfloat(inf);
- y = getfloat(inf);
- z = getfloat(inf);
- getnewline(inf);
- npnt = newpnt(x,y,z);
- npnt->attr = attr;
- addpoint(curobj,npnt);
- } else if(strcmp(buf,"endline") == 0) {
- getnewline(inf);
- break;
- } else if(strcmp(buf,"attr") == 0) {
- attr = newattr();
- attr->r = getfloat(inf);
- attr->g = getfloat(inf);
- attr->b = getfloat(inf);
- attr->nx = getfloat(inf);
- attr->ny = getfloat(inf);
- attr->nz = getfloat(inf);
- getnewline(inf);
- } else
- printf("getobj: bblat\n");
- }
- } else if(strcmp(buf,"beginloop") == 0) {
- getnewline(inf);
- curobj = newobj();
- curobj->type = OBJ_LOOP;
- curobj->next = objlist;
- objlist = curobj;
- while(getstr(inf,buf)) {
- if(strcmp(buf,"pnt") == 0) {
- x = getfloat(inf);
- y = getfloat(inf);
- z = getfloat(inf);
- getnewline(inf);
- npnt = newpnt(x,y,z);
- npnt->attr = attr;
- addpoint(curobj,npnt);
- } else if(strcmp(buf,"endloop") == 0) {
- getnewline(inf);
- break;
- } else if(strcmp(buf,"attr") == 0) {
- attr = newattr();
- attr->r = getfloat(inf);
- attr->g = getfloat(inf);
- attr->b = getfloat(inf);
- attr->nx = getfloat(inf);
- attr->ny = getfloat(inf);
- attr->nz = getfloat(inf);
- getnewline(inf);
- } else
- printf("getobj: bblat\n");
- }
- } else if(strcmp(buf,"beginpoints") == 0) {
- getnewline(inf);
- curobj = newobj();
- curobj->type = OBJ_POINTS;
- curobj->next = objlist;
- objlist = curobj;
- while(getstr(inf,buf)) {
- if(strcmp(buf,"pnt") == 0) {
- x = getfloat(inf);
- y = getfloat(inf);
- z = getfloat(inf);
- getnewline(inf);
- npnt = newpnt(x,y,z);
- npnt->attr = attr;
- addpoint(curobj,npnt);
- } else if(strcmp(buf,"endpoints") == 0) {
- getnewline(inf);
- break;
- } else if(strcmp(buf,"attr") == 0) {
- attr = newattr();
- attr->r = getfloat(inf);
- attr->g = getfloat(inf);
- attr->b = getfloat(inf);
- attr->nx = getfloat(inf);
- attr->ny = getfloat(inf);
- attr->nz = getfloat(inf);
- getnewline(inf);
- } else
- printf("getobj: bblat\n");
- }
- } else if(strcmp(buf,"attr") == 0) {
- attr = newattr();
- attr->r = getfloat(inf);
- attr->g = getfloat(inf);
- attr->b = getfloat(inf);
- attr->nx = getfloat(inf);
- attr->ny = getfloat(inf);
- attr->nz = getfloat(inf);
- getnewline(inf);
- } else if(strcmp(buf,"binarygeom") == 0) {
- printf("getobj: binary geom\n");
- } else
- printf("getobj: abalt\n");
- }
- return objlist;
- }
-
- object *twixtobj(obj1, obj2)
- object *obj1, *obj2;
- {
- point *pnt1, *pnt2;
- point *next1, *next2;
- object *objlist;
- object *curobj;
- int more;
-
- objlist = curobj = 0;
- while(obj1 && obj2) {
- pnt1 = obj1->points;
- pnt2 = obj2->points;
- while(1) {
- if(obj1->type==OBJ_LINE) {
- if (!(pnt1 && pnt2 && pnt1->next && pnt2->next))
- break;
- } else {
- if (!(pnt1 && pnt2))
- break;
- }
- if(!objlist) {
- objlist = curobj = newobj();
- } else {
- curobj->next = newobj();
- curobj = curobj->next;
- }
- if(obj1->type == OBJ_POINTS)
- curobj->type = OBJ_LINE;
- else
- curobj->type = OBJ_POLYGON;
- next1 = pnt1->next;
- if(!next1)
- next1 = obj1->points;
- next2 = pnt2->next;
- if(!next2)
- next2 = obj2->points;
- addpoint(curobj,clonepnt(pnt1));
- addpoint(curobj,clonepnt(pnt2));
- pnt1 = pnt1->next;
- pnt2 = pnt2->next;
- if(obj1->type != OBJ_POINTS) {
- addpoint(curobj,clonepnt(next2));
- addpoint(curobj,clonepnt(next1));
- }
- }
- obj1 = obj1->next;
- obj2 = obj2->next;
- }
- return objlist;
- }
-
- applyobj(obj,func)
- object *obj;
- int (*func)();
- {
- point *apnt;
-
- while(obj) {
- apnt = obj->points;
- while(apnt) {
- (func)(apnt);
- apnt = apnt->next;
- }
- obj = obj->next;
- }
- }
-
- objdomain(obj,px1,px2,py1,py2,pz1,pz2)
- object *obj;
- float *px1, *px2;
- float *py1, *py2;
- float *pz1, *pz2;
- {
- point *apnt;
- float x1, x2;
- float y1, y2;
- float z1, z2;
-
- x1 = 1000000.0;
- x2 = -1000000.0;
- y1 = 1000000.0;
- y2 = -1000000.0;
- z1 = 1000000.0;
- z2 = -1000000.0;
-
- while(obj) {
- apnt = obj->points;
- while (apnt) {
- if (apnt->x > x2) x2 = apnt->x;
- if (apnt->x < x1) x1 = apnt->x;
- if (apnt->y > y2) y2 = apnt->y;
- if (apnt->y < y1) y1 = apnt->y;
- if (apnt->z > z2) z2 = apnt->z;
- if (apnt->z < z1) z1 = apnt->z;
- apnt = apnt->next;
- }
- obj = obj->next;
- }
- *px1 = x1; *px2 = x2;
- *py1 = y1; *py2 = y2;
- *pz1 = z1; *pz2 = z2;
- }
-
- object *cloneobj(obj)
- object *obj;
- {
- object *robj, *cobj;
- point *pnt, *cpnt;
-
- cobj = robj = NULL;
- while(obj) {
- if(cobj) {
- cobj->next = newobj();
- cobj = cobj->next;
- } else
- cobj = robj = newobj();
- cobj->type = obj->type;
- if(obj->points) {
- pnt = obj->points;
- cpnt = clonepnt(pnt);
- cpnt->type = pnt->type;
- cobj->points = cpnt;
- pnt = pnt->next;
- while(pnt) {
- cpnt->next = clonepnt(pnt);
- cpnt = cpnt->next;
- cpnt->type = pnt->type;
- pnt = pnt->next;
- }
- }
- obj = obj->next;
- }
- return robj;
- }
-
- evertobj(obj)
- object *obj;
- {
- point *pntlist, *pnt, *epnt;;
-
- while(obj) {
- if(obj->points) {
- pntlist = pnt = obj->points;
- obj->points = 0;
- while(pnt) {
- epnt = clonepnt(pnt);
- epnt->next = obj->points;
- obj->points = epnt;
- pnt = pnt->next;
- }
- freepnts(pntlist);
- }
- obj = obj->next;
- }
- }
-
- objstats(obj)
- object *obj;
- {
- int polys, lines, loops, pointlists, points;
-
- polys = loops = lines = pointlists = points = 0;
- while(obj) {
- if(obj->type == OBJ_POINTS) {
- pointlists++;
- points += pntcount(obj);
- } else if(obj->type == OBJ_LINE) {
- lines++;
- points += pntcount(obj);
- } else if(obj->type == OBJ_LOOP) {
- loops++;
- points += pntcount(obj);
- } else if(obj->type == OBJ_POLYGON) {
- polys++;
- points += pntcount(obj);
- }
- obj = obj->next;
- }
- printf("objstat: %d polys %d loops %d lines %d pntlists. %d tot pnts\n",
- polys,loops,lines,pointlists,points);
- }
-
- pntcount(obj)
- object *obj;
- {
- point *pnt;
- int n;
-
- pnt = obj->points;
- n = 0;
- while(pnt) {
- n++;
- pnt = pnt->next;
- }
- return n;
- }
-
- stripobj(obj)
- object *obj;
- {
- point *pnt;
-
- while(obj) {
- if(obj->attr) {
- freeattr(obj->attr);
- obj->attr = 0;
- }
- pnt = obj->points;
- while(pnt) {
- if(pnt->attr) {
- freeattr(pnt->attr);
- pnt->attr = 0;
- }
- pnt = pnt->next;
- }
- obj = obj->next;
- }
- }
-